package cn.redragon.soa.common.amqp;


import cn.redragon.soa.common.amqp.model.MessageResponse;
import cn.redragon.soa.common.exception.ServiceException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

@Slf4j
public abstract class ReplyToListener {

    @Autowired
    @Qualifier(value = "commonObjectMapper")
    private ObjectMapper objectMapper;

    protected <T> String response(MessageProcessor<T> supplier) {
        MessageResponse<T> response = getMessageResponse(supplier);
        try {
            String respText = objectMapper.writeValueAsString(response);
            log.info("response content: {}", respText);
            return respText;
        } catch (JsonProcessingException e) {
            return "{\"code\":500 , \"msg\": \"Json Parse Error\"}";
        }
    }

    private <T> MessageResponse<T> getMessageResponse(MessageProcessor<T> supplier) {
        try {
            return new MessageResponse<>(supplier.process());
        } catch (ServiceException ex) {
            log.error(ex.getMessage(), ex);
            return MessageResponse.<T>builder()
                .code(ex.getCode())
                .build();
        } catch (RuntimeException ex) {
            // build an error response for exceptions like EntityNotFoundException / IllegalArgumentException
            // otherwise you have to wait MQ reply timeout
            log.error(ex.getMessage(), ex);
            return MessageResponse.<T>builder().build();
        }
    }

    public interface MessageProcessor<T> {

        T process() throws ServiceException;

    }
}
